import 'package:flutter/material.dart' hide showMenu;
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';
import 'package:kq_flutter_core_widget/extentions/kq_extentions.dart';
import '../../resources/kq_theme_colors.dart';
import 'package:kq_flutter_widgets/widgets/divider/kq_divider.dart';

import '../../theme/kq_theme_manager.dart';
import '../popMenu/kq_popup_menu.dart';

/// 弹出菜单
/// 支持宽度充满和气泡样式
/// 静态调用方式：
/// [KqDropDownMenu.showPopMenu(context: context, menuData: menuData)]，气泡弹窗，每行高度56，宽度自适应
/// [KqDropDownMenu.showFullWidthMenu(context: context, menuData: menuData)] ：下拉菜单，宽度充满屏幕，每行高度44
/// 也可以使用潜逃使用方式，然后用 [KqDropDownMenuController] 的 [showPopMenu] 或 [showFullWidthMenu]
/// 参考 [DropDownMenuDemo] 用法
class KqDropDownMenu extends StatefulWidget {
  /// 菜单从哪里弹出来，就放谁
  final Widget child;

  /// 菜单列表
  final List<KqDropMenuData> menuData;

  /// 选中回调
  final Function(KqDropMenuData menuData)? onSelected;

  /// 最大菜单数量，超过这个数量就滚动，默认6
  final int maxQty;

  /// 菜单控制器
  final KqDropDownMenuController menuController;

  const KqDropDownMenu({
    Key? key,
    required this.menuController,
    required this.menuData,
    required this.child,
    this.maxQty = 6,
    this.onSelected,
  }) : super(key: key);

  @override
  KqDropDownMenuState createState() => KqDropDownMenuState();

  /// 宽度充满屏幕的菜单
  static showFullWidthMenu(
      {required BuildContext context,
      required List<KqDropMenuData> menuData,
      int maxQty = 6,
      Function(KqDropMenuData menuData)? onSelected}) {
    final RenderBox button = context.findRenderObject()! as RenderBox;
    final RenderBox overlay =
        Navigator.of(context).overlay!.context.findRenderObject()! as RenderBox;
    final Offset offset = Offset(0.0, button.size.height);
    final RelativeRect position = RelativeRect.fromRect(
      Rect.fromPoints(
        button.localToGlobal(offset, ancestor: overlay),
        button.localToGlobal(button.size.bottomRight(Offset.zero) + offset,
            ancestor: overlay),
      ),
      Offset.zero & overlay.size,
    );
    showMenu(
      context: context,
      position: position,
      elevation: 0,
      color: KqThemeManager.getDialogConfig().bgColor,
      items: KqDropMenuData.buildItems(menuData),
      constraints: BoxConstraints(maxHeight: 44.r * maxQty),
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.zero),
      ),
    ).then<void>((KqDropMenuData? newValue) {
      if (newValue == null) {
        return null;
      }
      onSelected?.call(newValue);
    });
  }

  /// 宽度自适应的气泡菜单
  /// [selectedIndex] 如何需要默认选中某个则传
  /// [maxQty] 超过这个数则滚动
  /// [onSelected] 选择回调
  static showPopMenu(
      {required BuildContext context,
      required List<KqDropMenuData> menuData,
      int maxQty = 6,
      double? offsetX,
      double? offsetY,
      RelativeRect? customPosition,
      double? elevation,
      int? selectedIndex,
      Function(KqDropMenuData menuData)? onSelected}) {
    final RenderBox button = context.findRenderObject()! as RenderBox;
    final RenderBox overlay =
        Navigator.of(context).overlay!.context.findRenderObject()! as RenderBox;
    final Offset offset =
        Offset(offsetX ?? 0.0, button.size.height + (offsetY ?? 0));
    final RelativeRect position = customPosition ??
        RelativeRect.fromRect(
          Rect.fromPoints(
            button.localToGlobal(offset, ancestor: overlay),
            button.localToGlobal(button.size.bottomRight(Offset.zero) + offset,
                ancestor: overlay),
          ),
          Offset.zero & overlay.size,
        );
    if (selectedIndex != null) {
      for (int i = 0; i < (menuData.length); i++) {
        menuData[i].selected = selectedIndex == i;
      }
    }
    showMenu(
      context: context,
      position: position,
      elevation: elevation ?? 0,
      color: KqThemeManager.getDialogConfig().bgColor ?? KqThemeColors.bgWhite,
      items: KqDropMenuData.buildPopItems(menuData, textAlign: TextAlign.start),
      constraints: BoxConstraints(maxHeight: 56.r * maxQty),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(8.r)),
      ),
    ).then<void>((KqDropMenuData? newValue) {
      if (newValue == null) {
        return null;
      }
      onSelected?.call(newValue);
    });
  }
}

class KqDropDownMenuState extends State<KqDropDownMenu> {
  late List<KqDropMenuData> menuData;

  Offset? getOffset() {
    return context.position();
  }

  void setMenuData(List<KqDropMenuData> data) {
    setState(() {
      menuData = data;
    });
  }

  @override
  void initState() {
    menuData = widget.menuData;
    widget.menuController.bind(this);
    super.initState();
  }

  @override
  void didUpdateWidget(covariant KqDropDownMenu oldWidget) {
    menuData = widget.menuData;
    widget.menuController.bind(this);
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    widget.menuController.bind(this);
    return widget.child;
  }
}

class KqDropDownMenuController {
  KqDropDownMenuState? _state;

  bind(KqDropDownMenuState state) {
    _state = state;
  }

  /// 宽度充满屏幕的下拉菜单
  showFullWidthMenu({List<KqDropMenuData>? menuData}) {
    if (_state == null) {
      return;
    }
    final RenderBox button = _state!.context.findRenderObject()! as RenderBox;
    final RenderBox overlay = Navigator.of(_state!.context)
        .overlay!
        .context
        .findRenderObject()! as RenderBox;
    final Offset offset = Offset(0.0, button.size.height);
    final RelativeRect position = RelativeRect.fromRect(
      Rect.fromPoints(
        button.localToGlobal(offset, ancestor: overlay),
        button.localToGlobal(button.size.bottomRight(Offset.zero) + offset,
            ancestor: overlay),
      ),
      Offset.zero & overlay.size,
    );
    showMenu(
      context: _state!.context,
      position: position,
      elevation: 0,
      color: KqThemeManager.getDialogConfig().bgColor ?? KqThemeColors.bgWhite,
      items: KqDropMenuData.buildItems(menuData ?? _state!.menuData,
          textAlign: TextAlign.center),
      constraints: BoxConstraints(maxHeight: 44.r * _state!.widget.maxQty),
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.zero),
      ),
    ).then<void>((KqDropMenuData? newValue) {
      if (_state == null || !_state!.mounted) {
        return null;
      }
      if (newValue == null) {
        return null;
      }
      _state!.widget.onSelected?.call(newValue);
    });
  }

  /// 气泡菜单
  showPopMenu({
    List<KqDropMenuData>? menuData,
    double? offsetX,
    double? offsetY,
    RelativeRect? customPosition,
    double? elevation,
    int? selectedIndex,
  }) {
    if (_state == null) {
      return;
    }
    final RenderBox button = _state!.context.findRenderObject()! as RenderBox;
    final RenderBox overlay = Navigator.of(_state!.context)
        .overlay!
        .context
        .findRenderObject()! as RenderBox;
    final Offset offset =
        Offset(offsetX ?? 0.0, button.size.height + (offsetY ?? 0));
    final RelativeRect position = customPosition ??
        RelativeRect.fromRect(
          Rect.fromPoints(
            button.localToGlobal(offset, ancestor: overlay),
            button.localToGlobal(button.size.bottomRight(Offset.zero) + offset,
                ancestor: overlay),
          ),
          Offset.zero & overlay.size,
        );
    showMenu(
      context: _state!.context,
      position: position,
      elevation: elevation ?? 0,
      color: KqThemeManager.getDialogConfig().bgColor ?? KqThemeColors.bgWhite,
      items: KqDropMenuData.buildPopItems(menuData ?? _state!.menuData,
          textAlign: TextAlign.start),
      constraints: BoxConstraints(maxHeight: 56.r * _state!.widget.maxQty),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(8.r)),
      ),
    ).then<void>((KqDropMenuData? newValue) {
      if (_state == null || !_state!.mounted) {
        return null;
      }
      if (newValue == null) {
        return null;
      }
      _state!.widget.onSelected?.call(newValue);
    });
  }
}

class KqDropMenuData {
  /// 标题
  String title;

  /// 备用
  String? titleId;

  /// 是否选中，选中则文字颜色高亮
  bool selected;

  /// 备用
  dynamic extraData;

  KqDropMenuData(this.title,
      {this.selected = false, this.titleId, this.extraData});

  static List<KqPopupMenuItem<KqDropMenuData>> buildItems(
      List<KqDropMenuData> data,
      {TextAlign? textAlign}) {
    List<KqPopupMenuItem<KqDropMenuData>> list = [];
    for (int j = 0; j < data.length; j++) {
      KqDropMenuData item = data[j];
      list.add(KqPopupMenuItem<KqDropMenuData>(
        value: item,
        height: 44.5.r,
        padding: EdgeInsets.zero,
        child: Column(
          children: [
            SizedBox(
              height: 44.r,
              width: KqScreenUtil().screenWidth,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Expanded(
                      child: Text(
                    item.title,
                    maxLines: 1,
                    textAlign: textAlign ?? TextAlign.center,
                    overflow: TextOverflow.ellipsis,
                    style: TextStyle(
                        fontSize: 14.sp,
                        color: item.selected
                            ? (KqThemeManager.getPullDownMenuConfig()
                                    .selectColor ??
                                KqThemeColors.textBlue)
                            : (KqThemeManager.getPullDownMenuConfig()
                                    .defaultTextColor ??
                                KqThemeColors.text26)),
                  )),
                ],
              ),
            ),
            if (j < data.length - 1)
              KqDivider(
                color: KqThemeManager.getPullDownMenuConfig().dividerColor,
              )
          ],
        ),
      ));
    }
    return list;
  }

  static List<KqPopupMenuItem<KqDropMenuData>> buildPopItems(
      List<KqDropMenuData> data,
      {double? popMenuMinWidth,
      TextAlign? textAlign}) {
    List<KqPopupMenuItem<KqDropMenuData>> list = [];
    for (int j = 0; j < data.length; j++) {
      KqDropMenuData item = data[j];
      list.add(KqPopupMenuItem<KqDropMenuData>(
        value: item,
        height: 56.r,
        padding: EdgeInsets.zero,
        child: Column(
          children: [
            ConstrainedBox(
              constraints: BoxConstraints(minWidth: popMenuMinWidth ?? 120.r),
              child: SizedBox(
                height: 55.5.r,
                child: Padding(
                  padding: EdgeInsets.symmetric(horizontal: 16.r),
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Text(
                        item.title,
                        maxLines: 1,
                        textAlign: textAlign,
                        overflow: TextOverflow.ellipsis,
                        style: TextStyle(
                            fontSize: 14.sp,
                            color: item.selected
                                ? (KqThemeManager.getPullDownMenuConfig()
                                        .selectColor ??
                                    KqThemeColors.textBlue)
                                : (KqThemeManager.getPullDownMenuConfig()
                                        .defaultTextColor ??
                                    KqThemeColors.text26)),
                      ),
                    ],
                  ),
                ),
              ),
            ),
            Visibility(
                visible: j < data.length - 1,
                child: KqDivider(
                  color: KqThemeManager.getPullDownMenuConfig().dividerColor ??
                      KqThemeColors.bgF0,
                  leftMargin: 16.r,
                ))
          ],
        ),
      ));
    }
    return list;
  }
}
